﻿using System.IO;
using System.Web;
using System.Web.Caching;
using EPiServer;
using log4net;

namespace TemplateFoundation.Handlers.JavaScriptTranslate
{
    /// <summary>
    /// Used to serve a script file with a language translation object injected at the top
    /// </summary>
    public class ScriptLanguageInjectorHandler : IHttpHandler
    {
        private static readonly ILog _logger = LogManager.GetLogger(typeof (ScriptLanguageInjectorHandler));

        private static string GetScriptFileContents(string scriptPhysicalPath)
        {
            var content = CacheManager.RuntimeCacheGet(scriptPhysicalPath) as string;

            if (content==null)
            {
                _logger.DebugFormat("[ETF] Loading JavaScript from disk: {0}", scriptPhysicalPath);

                if (!File.Exists(scriptPhysicalPath))
                {
                    throw new FileNotFoundException("Unable to find requested script file", scriptPhysicalPath);
                }

                using (var reader = new StreamReader(scriptPhysicalPath))
                {
                    content = reader.ReadToEnd();
                }

                CacheManager.RuntimeCacheAdd(scriptPhysicalPath, content, new CacheDependency(scriptPhysicalPath));
            }

            return content;
        }

        #region IHttpHandler Members

        public bool IsReusable
        {
            get { return false; }
        }

        public void ProcessRequest(HttpContext context)
        {
            try
            {
                // Verify physical file exists
                var scriptFileVirtualPath = context.Request.Url.AbsolutePath;

                var scriptPhysicalPath = HttpContext.Current.Server.MapPath(scriptFileVirtualPath);

                if (!File.Exists(scriptPhysicalPath))
                {
                    context.Response.StatusCode = 404;
                    context.Response.Flush();

                    return;
                }

                var scriptContent = GetScriptFileContents(scriptPhysicalPath);

                context.Response.ContentType = "text/javascript";

                // Check if querystring parameter for language has been set
                var language = context.Request.QueryString["epslanguage"];

                if (!string.IsNullOrWhiteSpace(scriptContent) && !string.IsNullOrWhiteSpace(language))
                {
                    var translationScript = new LanguageScriptBuilder(ScriptLanguageManager.Instance).GetScript(language);

                    if (string.IsNullOrWhiteSpace(translationScript))
                    {
                        context.Response.StatusCode = 404;
                        context.Response.StatusDescription = "Language parameter set but no translations found";
                    }
                    else
                    {
                        scriptContent = scriptContent.Insert(0, translationScript);

                        context.Response.StatusCode = 200;
                        context.Response.StatusDescription = "JavaScript returned with appended translations object";
                        context.Response.Write(scriptContent);   
                    }
                }
                else
                {
                    context.Response.Write(scriptContent); // Original script without any language object added
                }
            }
            catch
            {
                context.Response.StatusCode = 500;
            }

            context.Response.Flush();
        }

        #endregion
    }
}